<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
 */
namespace App\Service\Api;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use Hyperf\Di\Annotation\Inject;
use Hyperf\DbConnection\Db;
use App\Utils\ServerUtil;
use App\Utils\ApiUtils;
use App\Dao\TaskDao;
use App\Dao\TaskFailDao;
use App\Model\Task;
use App\Utils\Redis;
use App\Utils\GrpcClient\OAClient;
use App\Utils\GrpcClient\CRMClient;
use App\Utils\GrpcClient\ERPClient;
use App\Utils\GRPCClient;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Codec\Json;
use Pb\Params;

class TaskService
{

    /**
     * @Inject
     * @var TaskDao
     */
    protected $dao;

    /**
     * @Inject
     * @var TaskFailDao
     */
    protected $fdao;

    public function test($params)
    {
        var_dump($params,'处理任务.............');
      
        return ApiUtils::send();
    }

    public function addTask($params)
    {
        $where = [];
        $where[] = ['task_no','=',$params['task_no']];
        $info = $this->dao->searchFirst($where);
        if(!empty($info)){
            throw new BusinessException(ErrorCode::ERR_SERVER ,'请不要提交重复任务');
        }
        Db::beginTransaction();
        try{
            //插入任务表
            $map['to_module_name'] = $params['to_module_name'];
            $map['from_module_name'] = $params['from_module_name'];
            $map['task_no'] = $params['task_no'];
            $map['name'] = $params['name'];
            $map['content'] = Json::encode($params['content']);
            $id = $this->dao->add($map);
            //插入失败表
            $map['task_id'] = $id;
            unset($map['name']);
            $this->fdao->add($map);
            Db::commit();
            return ApiUtils::send();
        } catch(\Throwable $t){
            Db::rollBack();
            throw new BusinessException(ErrorCode::ERR_SERVER ,$t->getMessage());
        }
      
        
    }

    public function execTask($params)
    {
        $content = Json::decode($params['content']);
        $module_name = $params['to_module_name'];
        list($reply, $status) = $this->sendGrpc($content,$module_name);
        if ($reply->getErrCode() == ErrorCode::SUCCESS) {
            Db::beginTransaction();
            try{
                $this->dao->update([['id','=',$params['task_id']]],['status'=>Task::SUCESS]);
                $this->fdao->delete([['id','=',$params['id']]]);
                Db::commit();
            } catch(\Throwable $t){
                Db::rollBack();
            }
        }else{
            Db::beginTransaction();
            try{
                $this->dao->update([['id','=',$params['task_id']]],['status'=>Task::FAIL,'reason'=>$reply->getMsg()]);
                $num = $params['num'] + 1;
                $this->fdao->update([['id','=',$params['id']]],['num'=> $num]);
                Db::commit();
            } catch(\Throwable $t){
                Db::rollBack();
            }
        }
        
    }

    public function sendGrpc($params,$module_name)
    {
        $request = new Params();
        $requestData = $params['data'];
        $request->setRequest(
            json_encode($requestData)
        );
        $request->setController($params['class_name']);
        $request->setMethod($params['method']);
        switch ($module_name) {
            case 'oa':
                $client = new OAClient();
                list($reply, $status) = $client->curdClient($request);
                return [$reply, $status];
                break;
            case 'crm':
                $client = new CRMClient();
                list($reply, $status) = $client->curdClient($request);
                return [$reply, $status];
                break;
            case 'erp':
                $client = new ERPClient();
                list($reply, $status) = $client->curdClient($request);
                return [$reply, $status];
                break;
            case 'chat':
                $client = new GRPCClient();
                list($reply, $status) = $client->curdClient($request);
                return [$reply, $status];
                break;
            default:
                $client = new GRPCClient();
                list($reply, $status) = $client->curdClient($request);
                return [$reply, $status];
                break;
        }
        
        
    }

    /**
     * 任务日志列表
     * @param $params
     * @return array
     */
    public function list($params)
    {
        $where = [];
        if (!empty($params['name'])) {
            $where[] = ['name', 'like', "%{$params['name']}%"];
        }

        if (!empty($params['start_time'])) {
            $where[] = ['add_time', '>=', strtotime($params['start_time'])];
        }

        if (!empty($params['end_time'])) {
            $where[] = ['add_time', '<', strtotime($params['end_time'])];
        }

        if (!empty($params['status'])) {
            $where[] = ['status', '=', $params['status']];
        }

        $list = $this->dao->getListPage($where, $params['page'], $params['pageSize']);
        
        return ApiUtils::send(ErrorCode::SUCCESS, '查询成功', $list['data'], $list['total']);
    }


}
